package org.hbhk.hxl.gateway.filter;

import org.hbhk.hxl.gateway.exception.RouteException;
import org.hbhk.hxl.gateway.route.IptUtil;
import org.hbhk.hxl.gateway.services.ServiceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import com.google.common.util.concurrent.RateLimiter;

import reactor.core.publisher.Mono;

/**
 * 
 * 服务限流管理
 */
@Component
public class RateLimiterFilter implements GlobalFilter, Ordered {

	private Logger log = LoggerFactory.getLogger(getClass());

	@Override
	public int getOrder() {
		return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 9;
	}

	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		ServerHttpRequest request = exchange.getRequest();
		String ip = IptUtil.getIpAddress(request);
		RateLimiter rateLimiter = ServiceUtil.getRateLimit(ip);
		if (rateLimiter != null) {
			if (!rateLimiter.tryAcquire()) {
				log.error("ip限流保护:" + ip);
				throw new RouteException("请求限流");
			}
			return chain.filter(exchange);
		}
		String url = request.getURI().getPath();
		rateLimiter = ServiceUtil.getRateLimit(url);
		if (rateLimiter == null) {
			return chain.filter(exchange);
		}
		if (!rateLimiter.tryAcquire()) {
			log.error("服务限流保护:" + url);
			throw new RouteException("请求限流:" + url);
		}
		return chain.filter(exchange);
	}

}